Repository navigation
SPIR-V: work around missing bfloat arithmetic legalization in the back-ends - #1076
Merged
Merged
Conversation
SPV_KHR_bfloat16 only covers storage and conversions: arithmetic, comparisons and math functions on `bfloat` need SPV_INTEL_bfloat16_arithmetic, which isn't a registered extension and which both back-ends require for them. So with only `supports_bfloat16` set, kernels using BFloat16 failed to compile. Widen these operations to `float` in `mcgen`, rounding the result back, unless the new `supports_bfloat16_arithmetic` flag is set. This has to happen there, after `prepare_execution!`, as its InstCombine narrows the widened operations back to `bfloat`. Julia's `DemoteFloat16` pass doesn't fit: it skips fast-math instructions and doesn't handle intrinsics. `fneg`, `fabs` and `copysign` operate on the bits instead, as conversions may change NaNs. `fma` is computed in `double` with round-to-odd, like Julia's codegen does for `fma_float`, so targets without double precision reject it, and `llvm.fmuladd` is unfused. `validate_ir` rejects the intrinsics that can't be widened, such as reductions. SPV_KHR_bfloat16 also defines conversions to `bfloat` as going through `float`, which rounds twice for doubles and for integers wider than its significand. Those are now rounded to `float` with round-to-odd first, as Julia 1.13's codegen does for integers.
Member
|
Closes/works around JuliaGPU/KernelAbstractions.jl#921? |
Member
Author
|
No it also needs a new PoCL JLL and KA.jl change, since we're not legalizing storage here, only arithmetic. |
Member
Author
|
That said, I'm not sure we even need this. It may be up to the SPIR-V code generator (LLVM's back-end, or the Khronos translator) to take care of legalizing LLVM IR. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1076 +/- ##
==========================================
- Coverage 92.48% 91.16% -1.33%
==========================================
Files 31 31
Lines 7334 7513 +179
==========================================
+ Hits 6783 6849 +66
- Misses 551 664 +113 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This was referenced Nov 3, 2026
POCL: support BFloat16 kernels when PoCL accepts SPV_KHR_bfloat16
JuliaGPU/KernelAbstractions.jl#946
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
With
supports_bfloat16set (i.e.SPV_KHR_bfloat16), the SPIR-V back-ends can store and convertbfloat, but abort on any arithmetic, comparison or math function on it unlessSPV_INTEL_bfloat16_arithmeticis enabled:That extension isn't in the SPIR-V registry (an EXT version is in progress, KhronosGroup/SPIRV-Registry#444),
spirv-valrejects it, and few consumers accept it. So BFloat16 arithmetic fails to compile on oneAPI.jl today, and on PoCL/OpenCL.jl once those enableSPV_KHR_bfloat16.This PR works around it: unless the new target flag
supports_bfloat16_arithmeticis set,mcgenperforms these operations onfloatand rounds the result back tobfloat. It also makes conversions tobfloatround once;SPV_KHR_bfloat16defines them via binary32, which rounds twice forFloat64and for integers wider than 24 bits.Ideally the back-end legalizes
bfloatitself, as other LLVM targets do: llvm/llvm-project#238375, which also covers storage on targets withoutSPV_KHR_bfloat16. This pass can be removed once that's fixed.Details:
mcgen, because the InstCombine inprepare_execution!would narrow the widened operations back tobfloat.fneg,fabsandcopysignwork on the bits, so NaNs are preserved.fmais computed indoublewith round-to-odd, and rejected on targets without fp64.fmuladdis computed unfused.validate_ir, not left for the back-end to abort on.Tested with
test/spirv/bfloat16.jl(FileCheck andspirv-valon both back-ends, plus host checks of the conversion andfmalowering against BigFloat), and end to end on KernelAbstractions' POCL back-end with a PoCL that acceptsSPV_KHR_bfloat16(JuliaPackaging/Yggdrasil#15429).